#include "stdafx.h"
#include "CppUnitTest.h"

#include "MxPluginManager\MxPluginManager1.h"
#include "PublicInterfaces\{FAFD3CB8-FCF3-46EE-B32E-45A4FF68073E}\IImageComputePluginLib.h"
#include "PublicInterfaces\{FAFD3CB8-FCF3-46EE-B32E-45A4FF68073E}\IImageCompute.h"
#include "PublicInterfaces\{FAFD3CB8-FCF3-46EE-B32E-45A4FF68073E}\IImageComputeFnDef.h"
#include "PublicInterfaces\{FAFD3CB8-FCF3-46EE-B32E-45A4FF68073E}\IImageComputeFn.h"

#include "..\..\PublicInterfaces\PluginICPopenCV\OCV-Dev-ProductID.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace PluginICPopenCVTest
{
	TEST_CLASS(GaussianImageTest)
	{
	private:
		MxPluginManager			*_pluginMngr;
		MxPluginLib				*_plugin;
		IImageComputePluginLib	*_lib;
		IImageCompute		    *_icp;
		IImageComputeFnDef		*_fnDef;
		IImageComputeFn			*_fn;

	public:

		TEST_METHOD_INITIALIZE(GaussianImgInit)
		{
			_pluginMngr = new MxPluginManager();
			if (_pluginMngr->RefreshPluginsInRootFolder(SID_ImageProc, true) == true)
			{
				if ((_plugin = _pluginMngr->GetPlugin(PRODID_PluginICPopenCV)) != nullptr)
				{
					if ((_lib = static_cast<IImageComputePluginLib *>(_plugin->CreateClassInstance(IImageComputePluginLibIID::Guid()))) != nullptr)
					{
						if((_icp = _lib->GetIImageCompute()) != nullptr)
						{
							GUID fnID = MxGUID::ConvertFromString("{4CCF13FA-B96F-4B79-9C7B-464A40722BEC}");
							_fnDef =_icp->GetIImageComputeFnDef(fnID);
							_fn =_icp->GetIImageComputeFn(fnID);
						}
					}
				}
			}
		}

		TEST_METHOD_CLEANUP(GaussianImgDeinit)
		{
			if(_fn != nullptr)
				_fn->DestroyPtr();
			_fn = nullptr;

			if(_fnDef!= nullptr)
				_fnDef->DestroyPtr();
			_fnDef = nullptr;

			if(_icp != nullptr)
				_icp->DestroyPtr();
			_icp = nullptr;

			if(_lib != nullptr)
				_lib->DestroyPtr();
			_lib = nullptr;

			if (_pluginMngr != nullptr)
				delete _pluginMngr;
			_pluginMngr = nullptr;
		}
		
		TEST_METHOD(GaussianImgCreateTest)
		{
			Assert::IsNotNull(_fnDef);
			Assert::IsTrue(_fnDef->IsValid());

			Assert::IsNotNull(_fn);
			Assert::IsTrue(_fn->IsValid());
		}

		TEST_METHOD(GaussianImgFnDefParamsTest)
		{
			Assert::IsNotNull(_fnDef);
			Assert::IsTrue(_fnDef->IsValid());

			Assert::AreEqual("GaussianImg", _fnDef->GetLabel());
			Assert::AreEqual("Smooth the image using Gaussian", _fnDef->GetDescription());
			Assert::AreEqual("Common", _fnDef->GetToolboxClass());
			Assert::AreEqual("Gaussian", _fnDef->GetToolboxLabel());
			Assert::AreEqual(2, _fnDef->GetToolboxIconClassOffset());

			Assert::AreEqual(8, _fnDef->GetParamCount(IImageComputeFnDef::Direction::Input));
			Assert::AreEqual(0, _fnDef->GetParamCount(IImageComputeFnDef::Direction::Output));
			Assert::AreEqual(2, _fnDef->GetParamCount(IImageComputeFnDef::Direction::IO));

			Assert::AreEqual("StopProc", _fnDef->GetParamName(IImageComputeFnDef::Direction::IO, 0));
			Assert::AreEqual("ImageRef", _fnDef->GetParamName(IImageComputeFnDef::Direction::IO, 1));
			Assert::AreEqual("RootFolder", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 0));
			Assert::AreEqual("IJC", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 1));
			Assert::AreEqual("IJF", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 2));
			Assert::AreEqual("KernelHt", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 3));
			Assert::AreEqual("KernelWd", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 4));
			Assert::AreEqual("SigmaX", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 5));
			Assert::AreEqual("SigmaY", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 6));
			Assert::AreEqual("Border", _fnDef->GetParamName(IImageComputeFnDef::Direction::Input, 7));

			Assert::IsTrue(IImageComputeFnDef::Direction::IO == _fnDef->GetParamDirection("StopProc"));
			Assert::IsTrue(IImageComputeFnDef::Direction::Input == _fnDef->GetParamDirection("RootFolder"));
			Assert::IsTrue(IImageComputeFnDef::Direction::Input == _fnDef->GetParamDirection("IJC"));
			Assert::IsTrue(IImageComputeFnDef::Direction::Input == _fnDef->GetParamDirection("IJF"));
			Assert::IsTrue(IImageComputeFnDef::Direction::IO == _fnDef->GetParamDirection("ImageRef"));
			Assert::IsTrue(IImageComputeFnDef::Direction::Input == _fnDef->GetParamDirection("KernelHt"));
			Assert::IsTrue(IImageComputeFnDef::Direction::Input == _fnDef->GetParamDirection("KernelWd"));
			Assert::IsTrue(IImageComputeFnDef::Direction::Input == _fnDef->GetParamDirection("SigmaX"));
			Assert::IsTrue(IImageComputeFnDef::Direction::Input == _fnDef->GetParamDirection("SigmaY"));
			Assert::IsTrue(IImageComputeFnDef::Direction::Input == _fnDef->GetParamDirection("Border"));

			
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("StopProc")) == IImageComputeFnDef::ParamType::Bool);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("RootFolder")) == IImageComputeFnDef::ParamType::String);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("IJC")) == IImageComputeFnDef::ParamType::String);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("IJF")) == IImageComputeFnDef::ParamType::String);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("ImageRef")) == IImageComputeFnDef::ParamType::String);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("KernelHt")) == IImageComputeFnDef::ParamType::Integer);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("KernelWd")) == IImageComputeFnDef::ParamType::Integer);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("SigmaX")) == IImageComputeFnDef::ParamType::Double);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("SigmaY")) == IImageComputeFnDef::ParamType::Double);
			Assert::IsTrue(_fnDef->ConvertStrToParamType(_fnDef->GetParamValType("Border")) == IImageComputeFnDef::ParamType::Integer);

			Assert::AreEqual(_fnDef->ConvertParamTypeToStr(IImageComputeFnDef::ParamType::String), _fnDef->GetParamValType("RootFolder"));

			Assert::IsFalse(_fnDef->IsParamValMinSet("RootFolder"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("RootFolder"));
			Assert::IsFalse(_fnDef->IsParamValMinSet("IJC"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("IJC"));
			Assert::IsFalse(_fnDef->IsParamValMinSet("IJF"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("IJF"));
			Assert::IsFalse(_fnDef->IsParamValMinSet("ImageRef"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("ImageRef"));
			Assert::IsTrue(_fnDef->IsParamValMinSet("KernelHt"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("KernelHt"));
			Assert::IsTrue(_fnDef->IsParamValMinSet("KernelWd"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("KernelWd"));
			Assert::IsTrue(_fnDef->IsParamValMinSet("SigmaX"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("SigmaX"));
			Assert::IsTrue(_fnDef->IsParamValMinSet("SigmaY"));
			Assert::IsFalse(_fnDef->IsParamValMaxSet("SigmaY"));
			Assert::IsTrue(_fnDef->IsParamValMinSet("Border"));
			Assert::IsTrue(_fnDef->IsParamValMaxSet("Border"));

			Assert::AreEqual(0, _fnDef->GetParamValMin("KernelHt"));
			Assert::AreEqual(0, _fnDef->GetParamValMin("KernelWd"));
			Assert::AreEqual(0.0, _fnDef->GetParamDoubleValMin("SigmaX"));
			Assert::AreEqual(0.0, _fnDef->GetParamDoubleValMin("SigmaY"));
			Assert::AreEqual(0, _fnDef->GetParamValMin("Border"));
			Assert::AreEqual(5, _fnDef->GetParamValMax("Border"));

			Assert::AreEqual("no", _fnDef->GetParamDefaultVal("StopProc"));
			Assert::AreEqual("-", _fnDef->GetParamDefaultVal("RootFolder"));
			Assert::AreEqual("-", _fnDef->GetParamDefaultVal("IJC"));
			Assert::AreEqual("-", _fnDef->GetParamDefaultVal("IJF"));
			Assert::AreEqual("-", _fnDef->GetParamDefaultVal("ImageRef"));
			Assert::AreEqual("3", _fnDef->GetParamDefaultVal("KernelHt"));
			Assert::AreEqual("3", _fnDef->GetParamDefaultVal("KernelWd"));
			Assert::AreEqual("0.0", _fnDef->GetParamDefaultVal("SigmaX"));
			Assert::AreEqual("0.0", _fnDef->GetParamDefaultVal("SigmaY"));
			Assert::AreEqual("0", _fnDef->GetParamDefaultVal("Border"));

			Assert::AreEqual("Stop", _fnDef->GetParamLabel("StopProc"));
			Assert::AreEqual("Root folder", _fnDef->GetParamLabel("RootFolder"));
			Assert::AreEqual("IJC id", _fnDef->GetParamLabel("IJC"));
			Assert::AreEqual("IJF id", _fnDef->GetParamLabel("IJF"));
			Assert::AreEqual("ImageRef", _fnDef->GetParamLabel("ImageRef"));
			Assert::AreEqual("Kernel Height", _fnDef->GetParamLabel("KernelHt"));
			Assert::AreEqual("Kernel Width", _fnDef->GetParamLabel("KernelWd"));
			Assert::AreEqual("Sigma X", _fnDef->GetParamLabel("SigmaX"));
			Assert::AreEqual("Sigma Y", _fnDef->GetParamLabel("SigmaY"));
			Assert::AreEqual("Border Type", _fnDef->GetParamLabel("Border"));

			Assert::AreEqual("Do not process this step or any further steps", _fnDef->GetParamDesc("StopProc"));
			Assert::AreEqual("folder for project root", _fnDef->GetParamDesc("RootFolder"));
			Assert::AreEqual("GUID for job collection", _fnDef->GetParamDesc("IJC"));
			Assert::AreEqual("GUID for job file", _fnDef->GetParamDesc("IJF"));
			Assert::AreEqual("name of input image in ImageFolder without filetype", _fnDef->GetParamDesc("ImageRef"));
			Assert::AreEqual("Height of kernel used for smoothing - must be positive and odd (SigmaX used if 0)", _fnDef->GetParamDesc("KernelHt"));
			Assert::AreEqual("Width of kernel used for smoothing - must be positive and odd (SigmaY used if 0)", _fnDef->GetParamDesc("KernelWd"));
			Assert::AreEqual("kernel standard deviation in X direction (KernelX,Y used if 0.0)", _fnDef->GetParamDesc("SigmaX"));
			Assert::AreEqual("kernel standard deviation in Y direction (Sigma X used as value if 0.0)", _fnDef->GetParamDesc("SigmaY"));
			Assert::AreEqual("0=BORDER_DEFAULT, 1=BORDER_REPLICATE, 2=BORDER_REFLECT, 3=BORDER_REFLECT_101, 4=BORDER_WRAP, 5=BORDER_CONSTANT", _fnDef->GetParamDesc("Border"));
		}

		TEST_METHOD(GaussianImgRunTest)
		{
			Assert::IsNotNull(_fn);
			Assert::IsTrue(_fn->IsValid());

			Assert::IsTrue(_fn->InitCall(0, ".bmp", true, true));

			Assert::IsTrue(_fn->SetParamBool("StopProc", false));
			Assert::IsTrue(_fn->SetParamStr("RootFolder", "..\\..\\..\\TestImages"));
			Assert::IsTrue(_fn->SetParamStr("IJC", "IJC"));
			Assert::IsTrue(_fn->SetParamStr("IJF", "IJF"));
			Assert::IsTrue(_fn->SetParamStr( "ImageRef", "GaussianTest"));
			Assert::IsTrue(_fn->SetParamInt("KernelHt", 9));
			Assert::IsTrue(_fn->SetParamInt("KernelWd", 9));
			Assert::IsTrue(_fn->SetParamDouble("SigmaX", 0.0));
			Assert::IsTrue(_fn->SetParamDouble("SigmaY", 0.0));
			Assert::IsTrue(_fn->SetParamInt("Border", 0));

			Assert::IsTrue(_fn->ValidateCall());
			Assert::IsTrue(_fn->DoCall());
		}

	};
}